package org.budo.elasticsearch.jdbc.driver.parser.jsql;

import java.sql.SQLException;

import org.budo.elasticsearch.jdbc.driver.statement.DESC_TABLE;
import org.budo.elasticsearch.jdbc.driver.statement.DeleteStatement;
import org.budo.elasticsearch.jdbc.driver.statement.InsertStatement;
import org.budo.elasticsearch.jdbc.driver.statement.SHOW_DATABASES;
import org.budo.elasticsearch.jdbc.driver.statement.SHOW_FULL_TABLES;
import org.budo.elasticsearch.jdbc.driver.statement.SHOW_TABLES;
import org.budo.elasticsearch.jdbc.driver.statement.SHOW_TABLE_STATUS;
import org.budo.elasticsearch.jdbc.driver.statement.SelectStatement;
import org.budo.elasticsearch.jdbc.driver.statement.UpdateStatement;
import org.budo.jdbc.driver.parser.AbstractSqlStatementParser;
import org.budo.jdbc.driver.statement.JdbcStatement;
import org.budo.support.jsqlparser.JSqlParserUtil;

import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.update.Update;

/**
 * @author limingwei
 */
public class ElasticsearchJSqlStatementParser extends AbstractSqlStatementParser {
    @Override
    public JdbcStatement parse(String sql) throws SQLException {
        String _sql = sql.trim().toUpperCase();

        if (_sql.startsWith("SHOW FULL TABLES")) {
            return new SHOW_FULL_TABLES(sql);
        }

        if (_sql.startsWith("SHOW TABLE STATUS")) {
            return new SHOW_TABLE_STATUS(sql);
        }

        if (_sql.startsWith("DESC")) {
            return new DESC_TABLE(sql);
        }

        return super.parse(sql);
    }

    @Override
    protected JdbcStatement doParseSql(String sql) throws Throwable {
        if ("SHOW TABLES".equalsIgnoreCase(sql.trim())) {
            return new SHOW_TABLES();
        }

        if ("SHOW DATABASES".equalsIgnoreCase(sql.trim())) {
            return new SHOW_DATABASES();
        }

        Statement statement = JSqlParserUtil.parse(sql);
        String tableName = JSqlParserUtil.getTableName(statement);

        if (statement instanceof Select) {
            return new SelectStatement() //
                    .tableName(tableName) //
                    .setSqlStatement(new JSqlParserStatement() //
                            .setStatement(statement))
                    .setSql(sql);
        }

        if (statement instanceof Insert) {
            return new InsertStatement() //
                    .tableName(tableName) //
                    .setSqlStatement(new JSqlParserStatement().setStatement(statement)) //
                    .setSql(sql);
        }

        if (statement instanceof Update) {
            return new UpdateStatement() //
                    .tableName(tableName) //
                    .setSqlStatement(new JSqlParserStatement().setStatement(statement)) //
                    .setSql(sql);
        }

        if (statement instanceof Delete) {
            return new DeleteStatement() //
                    .tableName(tableName) //
                    .setSqlStatement(new JSqlParserStatement().setStatement(statement)) //
                    .setSql(sql);
        }

        throw new UnsupportedOperationException("#94 sql=" + sql);
    }
}